export default class Mode2 {
  constructor(sweeper) {
    this.sweeper = sweeper
    this.protect = 0
    this.settings = sweeper.settings
  }
  //初始化游戏
  initGame(mesh) {
    this.sweeper.numData = new Array()
    let numData = this.sweeper.numData
    let difficulty = this.sweeper.difficulty
    let counter = this.sweeper.counter
    let gameLine = this.sweeper.gameLine
    let site = {
      //记录初始点坐标
      x: parseInt(parseInt(mesh.name) / 10000) % 100,
      y: parseInt(parseInt(mesh.name) / 100) % 100,
      z: parseInt(mesh.name) % 100
    }
    //数组初始化
    for (let x = 0; x < difficulty.ux; x++) {
      numData[x] = new Array()
      for (let y = 0; y < difficulty.uy; y++) {
        //这种写法可以初始化为0
        numData[x][y] = new Array(difficulty.uz).fill(0)
      }
    }
    //随机生成雷
    while (counter.mineNum > 0) {
      let rem = {
        x: Math.floor(Math.random() * difficulty.ux),
        y: Math.floor(Math.random() * difficulty.uy),
        z: Math.floor(Math.random() * difficulty.uz)
      }
      //雷未生成且非初始点
      if (numData[rem.x][rem.y][rem.z] == 0 && (rem.x != site.x || rem.y != site.y || rem.z != site.z)) {
        numData[rem.x][rem.y][rem.z] = -1
        counter.mineNum--
      }
    }
    counter.mineNum = counter.countNum
    //判断面上的数字
    for (let x = 0; x < difficulty.ux; x++) {
      for (let y = 0; y < difficulty.uy; y++) {
        for (let z = 0; z < difficulty.uz; z++) {
          if (numData[x][y][z] == -1) continue //此处必须用continue，break会跳出三层
          /* different1 */
          let num = 0
          if (isMine(x + 1, y + 1, z + 1)) num++
          if (isMine(x + 1, y + 1, z - 1)) num++
          if (isMine(x + 1, y + 1, z)) num++
          if (isMine(x + 1, y - 1, z + 1)) num++
          if (isMine(x + 1, y - 1, z - 1)) num++
          if (isMine(x + 1, y - 1, z)) num++
          if (isMine(x + 1, y, z + 1)) num++
          if (isMine(x + 1, y, z - 1)) num++
          if (isMine(x + 1, y, z)) num++
          if (isMine(x - 1, y + 1, z + 1)) num++
          if (isMine(x - 1, y + 1, z - 1)) num++
          if (isMine(x - 1, y + 1, z)) num++
          if (isMine(x - 1, y - 1, z + 1)) num++
          if (isMine(x - 1, y - 1, z - 1)) num++
          if (isMine(x - 1, y - 1, z)) num++
          if (isMine(x - 1, y, z + 1)) num++
          if (isMine(x - 1, y, z - 1)) num++
          if (isMine(x - 1, y, z)) num++
          if (isMine(x, y + 1, z + 1)) num++
          if (isMine(x, y + 1, z - 1)) num++
          if (isMine(x, y + 1, z)) num++
          if (isMine(x, y - 1, z + 1)) num++
          if (isMine(x, y - 1, z - 1)) num++
          if (isMine(x, y - 1, z)) num++
          if (isMine(x, y, z + 1)) num++
          if (isMine(x, y, z - 1)) num++
          numData[x][y][z] = num
          /* different1 */
          //判断该坐标的合法性及是否是雷
          function isMine(x, y, z) {
            if (numData[x] && numData[x][y] && numData[x][y][z] && numData[x][y][z] == -1) return true
            else return false
          }
        }
      }
    }
    //计时器开始计时
    gameLine.timeStart()
  }
  //自动判雷功能
  automatic() {
    if(!this.settings.flagSchools || !this.settings.autoFlag){
      return false
    }
    if (this.sweeper.gameLine.gameOver) {
      return false
    }
    let difficulty = this.sweeper.difficulty
    let counter = this.sweeper.counter
    let group = this.sweeper.threeManager.group
    let numData = this.sweeper.numData
    let meshCover = this.sweeper.threeManager.meshCover
    let gameLine = this.sweeper.gameLine
    if (!numData) {
      return false
    }
    //判断的雷能否确定
    for (let x = 0; x < difficulty.ux; x++) {
      for (let y = 0; y < difficulty.uy; y++) {
        for (let z = 0; z < difficulty.uz; z++) {
          doFlag(x, y, z)
        }
      }
    }
    return gameLine.ifWin()
    function doFlag(x, y, z) {
      //判断坐标合法性
      if (x < 0 || x >= difficulty.ux || y < 0 || y >= difficulty.uy || z < 0 || z >= difficulty.uz) {
        return false
      }

      if (numData[x][y][z] != -1) {
        //不是雷直接返回
        return false
      }
      //如果这个雷之前被确定过了，直接返回
      if (group.children[x].children[y].children[z].know) {
        return false
      }
      //判断该雷能否判断为已知(周围全部为已知的)
      if (
        ifMesh(x + 1, y + 1, z + 1) &&
        ifMesh(x + 1, y + 1, z - 1) &&
        ifMesh(x + 1, y + 1, z) &&
        ifMesh(x + 1, y - 1, z + 1) &&
        ifMesh(x + 1, y - 1, z - 1) &&
        ifMesh(x + 1, y - 1, z) &&
        ifMesh(x + 1, y, z + 1) &&
        ifMesh(x + 1, y, z - 1) &&
        ifMesh(x + 1, y, z) &&
        ifMesh(x - 1, y + 1, z + 1) &&
        ifMesh(x - 1, y + 1, z - 1) &&
        ifMesh(x - 1, y + 1, z) &&
        ifMesh(x - 1, y - 1, z + 1) &&
        ifMesh(x - 1, y - 1, z - 1) &&
        ifMesh(x - 1, y - 1, z) &&
        ifMesh(x - 1, y, z + 1) &&
        ifMesh(x - 1, y, z - 1) &&
        ifMesh(x - 1, y, z) &&
        ifMesh(x, y + 1, z + 1) &&
        ifMesh(x, y + 1, z - 1) &&
        ifMesh(x, y + 1, z) &&
        ifMesh(x, y - 1, z + 1) &&
        ifMesh(x, y - 1, z - 1) &&
        ifMesh(x, y - 1, z) &&
        ifMesh(x, y, z + 1) &&
        ifMesh(x, y, z - 1)
      ) {
        //注意，仅仅插旗不会设为已知，必须识别之后才能设置，且此时的插旗状态不能取消
        group.children[x].children[y].children[z].know = true
        group.children[x].children[y].children[z].material = meshCover.numCovers[0]
        if (!group.children[x].children[y].children[z].flag) {
          group.children[x].children[y].children[z].flag = true
          if (!isNaN(counter.countNum)) counter.countNum--
          //如果插完旗判断当前胜负情况
          // GameLine.ifWin()
        }
        return true
      }

      function ifMesh(x1, y1, z1) {
        //判断坐标合法性，不合法坐标默认为已知
        if (x1 < 0 || x1 >= difficulty.ux || y1 < 0 || y1 >= difficulty.uy || z1 < 0 || z1 >= difficulty.uz) {
          return true
        }
        if (numData[x1][y1][z1] == -1) {
          //假装自己已知判断其他的能否为已知
          group.children[x].children[y].children[z].know = true
          doFlag(x1, y1, z1)
          group.children[x].children[y].children[z].know = false
        }
        return group.children[x1].children[y1].children[z1].know
      }
    }

  }
  //挖掘操作
  handleDig(meshObj) {
    if(!meshObj.visible){
      return false
    }
    let scope = this
    let gameLine = this.sweeper.gameLine
    let numData = this.sweeper.numData
    let difficulty = this.sweeper.difficulty
    let counter = this.sweeper.counter
    let meshCover = this.sweeper.threeManager.meshCover
    let group = this.sweeper.threeManager.group
    let site = {
      x: parseInt(meshObj.name / 10000) % 100,
      y: parseInt(meshObj.name / 100) % 100,
      z: meshObj.name % 100
    }
    //可以挖掘的方块设置为已知
    if(numData[site.x][site.y][site.z]!=-1){
      meshObj.know = true
      counter.knowNum++
    }
    switch (numData[site.x][site.y][site.z]) {
      case -1: //游戏结束
        gameLine.gameLose()
        return false
      case 0:
        //首先隐藏方块
        meshObj.visible = false
        //计时保护开始
        let runtime //loading时的时间补偿
        if (scope.protect == 0) {
          setTimeout(function () {
            // document.getElementById('loading_box').style.visibility = 'visible'
            runtime = new Date().getTime()
          })
        }
        scope.protect++
        doClick(site.x - 1, site.y - 1, site.z)
        doClick(site.x - 1, site.y, site.z)
        doClick(site.x - 1, site.y + 1, site.z)
        doClick(site.x, site.y - 1, site.z)
        doClick(site.x, site.y + 1, site.z)
        doClick(site.x + 1, site.y - 1, site.z)
        doClick(site.x + 1, site.y, site.z)
        doClick(site.x + 1, site.y + 1, site.z)
        doClick(site.x, site.y, site.z - 1)
        doClick(site.x, site.y, site.z + 1)
        doClick(site.x - 1, site.y, site.z - 1)
        doClick(site.x + 1, site.y, site.z - 1)
        doClick(site.x - 1, site.y, site.z + 1)
        doClick(site.x + 1, site.y, site.z + 1)
        doClick(site.x, site.y - 1, site.z - 1)
        doClick(site.x, site.y + 1, site.z - 1)
        doClick(site.x, site.y - 1, site.z + 1)
        doClick(site.x, site.y + 1, site.z + 1)
        //计时保护结束
        scope.protect--
        if (scope.protect == 0) {
          setTimeout(function () {
            // document.getElementById('loading_box').style.visibility = 'hidden'
            //计时补偿
            runtime = new Date().getTime() - runtime
            gameLine.beginTime = gameLine.beginTime - runtime
          }, 100)
        }
        function doClick(x, y, z) {
          //先判断存不存在,能不能点
          if (x < 0 || x >= difficulty.ux || y < 0 || y >= difficulty.uy || z < 0 || z >= difficulty.uz) {
            return
          }
          let mesh = group.children[x].children[y].children[z]
          //判断能不能挖
          if (mesh.flag || mesh.know || !mesh.visible) {
            return
          }
          scope.handleDig(mesh)
        }
        break
      default:
        //其余数字
        let faceNum = numData[site.x][site.y][site.z]
        meshObj.material = meshCover.numCovers[faceNum + 4]
        break
    }
    return true
  }
  //点击数字方块
  handleNum(meshObj) {
    if(!this.settings.clickNum){
      return false
    }
    let scope = this
    let numData = this.sweeper.numData
    let difficulty = this.sweeper.difficulty
    let group = this.sweeper.threeManager.group
    let musicCtrl = this.sweeper.musicCtrl
    let gameLine = this.sweeper.gameLine
    let site = {
      x: parseInt(meshObj.name / 10000) % 100,
      y: parseInt(meshObj.name / 100) % 100,
      z: meshObj.name % 100
    }
    let hadDig = false
    let counter = 0
    if (getMeshFlag(site.x + 1, site.y + 1, site.z + 1)) counter++
    if (getMeshFlag(site.x + 1, site.y + 1, site.z - 1)) counter++
    if (getMeshFlag(site.x + 1, site.y + 1, site.z)) counter++
    if (getMeshFlag(site.x + 1, site.y - 1, site.z + 1)) counter++
    if (getMeshFlag(site.x + 1, site.y - 1, site.z - 1)) counter++
    if (getMeshFlag(site.x + 1, site.y - 1, site.z)) counter++
    if (getMeshFlag(site.x + 1, site.y, site.z + 1)) counter++
    if (getMeshFlag(site.x + 1, site.y, site.z - 1)) counter++
    if (getMeshFlag(site.x + 1, site.y, site.z)) counter++
    if (getMeshFlag(site.x - 1, site.y + 1, site.z + 1)) counter++
    if (getMeshFlag(site.x - 1, site.y + 1, site.z - 1)) counter++
    if (getMeshFlag(site.x - 1, site.y + 1, site.z)) counter++
    if (getMeshFlag(site.x - 1, site.y - 1, site.z + 1)) counter++
    if (getMeshFlag(site.x - 1, site.y - 1, site.z - 1)) counter++
    if (getMeshFlag(site.x - 1, site.y - 1, site.z)) counter++
    if (getMeshFlag(site.x - 1, site.y, site.z + 1)) counter++
    if (getMeshFlag(site.x - 1, site.y, site.z - 1)) counter++
    if (getMeshFlag(site.x - 1, site.y, site.z)) counter++
    if (getMeshFlag(site.x, site.y + 1, site.z + 1)) counter++
    if (getMeshFlag(site.x, site.y + 1, site.z - 1)) counter++
    if (getMeshFlag(site.x, site.y + 1, site.z)) counter++
    if (getMeshFlag(site.x, site.y - 1, site.z + 1)) counter++
    if (getMeshFlag(site.x, site.y - 1, site.z - 1)) counter++
    if (getMeshFlag(site.x, site.y - 1, site.z)) counter++
    if (getMeshFlag(site.x, site.y, site.z + 1)) counter++
    if (getMeshFlag(site.x, site.y, site.z - 1)) counter++
    if(counter == numData[site.x][site.y][site.z]){
      tryDig(site.x + 1, site.y + 1, site.z + 1)
      tryDig(site.x + 1, site.y + 1, site.z - 1)
      tryDig(site.x + 1, site.y + 1, site.z)
      tryDig(site.x + 1, site.y - 1, site.z + 1)
      tryDig(site.x + 1, site.y - 1, site.z - 1)
      tryDig(site.x + 1, site.y - 1, site.z)
      tryDig(site.x + 1, site.y, site.z + 1)
      tryDig(site.x + 1, site.y, site.z - 1)
      tryDig(site.x + 1, site.y, site.z)
      tryDig(site.x - 1, site.y + 1, site.z + 1)
      tryDig(site.x - 1, site.y + 1, site.z - 1)
      tryDig(site.x - 1, site.y + 1, site.z)
      tryDig(site.x - 1, site.y - 1, site.z + 1)
      tryDig(site.x - 1, site.y - 1, site.z - 1)
      tryDig(site.x - 1, site.y - 1, site.z)
      tryDig(site.x - 1, site.y, site.z + 1)
      tryDig(site.x - 1, site.y, site.z - 1)
      tryDig(site.x - 1, site.y, site.z)
      tryDig(site.x, site.y + 1, site.z + 1)
      tryDig(site.x, site.y + 1, site.z - 1)
      tryDig(site.x, site.y + 1, site.z)
      tryDig(site.x, site.y - 1, site.z + 1)
      tryDig(site.x, site.y - 1, site.z - 1)
      tryDig(site.x, site.y - 1, site.z)
      tryDig(site.x, site.y, site.z + 1)
      tryDig(site.x, site.y, site.z - 1)
    }
    if(!gameLine.gameOver && !scope.automatic() && !gameLine.ifWin() && hadDig){
      musicCtrl.playGameAudio({ type: 'dig' })
    }
    //判断坐标是否合法
    function inBox(x,y,z){
      if (x < 0 || x >= difficulty.ux || y < 0 || y >= difficulty.uy || z < 0 || z >= difficulty.uz) {
        return false
      }
      return true
    }
    //获取模型对象
    function getMeshFlag(x,y,z){
      if(inBox(x,y,z)){
        return group.children[x].children[y].children[z].flag
      }else{
        return false
      }
    }
    //进行挖掘操作
    function tryDig(x,y,z){
      if(gameLine.gameOver){
        return
      }
      if(inBox(x,y,z)){
        let mesh = group.children[x].children[y].children[z]
        if(!mesh.flag && !mesh.know && mesh.visible){
          if(numData[x][y][z]==-1){
            gameLine.gameLose()
            return
          }
          scope.handleDig(mesh)
          hadDig = true
        }
      }
    }
  }
}
